import { EnumBetResult, EnumBjlResult } from "@/models/enums/EnumBjlResult";
import { RecmInfo, RoundInfo } from "../ExecutePlan";
import { IMoneyStrategy } from "../IMoneyStrategy";

export interface INormalStepOption {
    startMoney: number;
    addStep: number;
    devideStep: number;
    reverse: boolean; //true:赢了+100，输了-100
    resetLevel: number;
    baseMoney: number;
    betArray?: EnumBjlResult[];
}
export class NormalStepMoneyStrategy implements IMoneyStrategy {
    option: INormalStepOption;
    prevMoney: number = 0;
    currentMoney: number = 0;
    gameStart: boolean = false;
    startIndex: number = 0;
    baseMoney: number = 0;
    startMoney: number = 0;
    recmV: EnumBjlResult = EnumBjlResult.U;
    orecmV: EnumBjlResult = EnumBjlResult.U;
    orecmMoney: number = 0;

    constructor(name: string, option?: INormalStepOption | null, start?: boolean) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                baseMoney: 100,
                startMoney: 100,
                addStep: 100,
                devideStep: -100,
                reverse: false,
                resetLevel: 800,
            };
        }
        if (start) this.gameStart = true;
        else this.gameStart = false;
        this.resetStrategy();
    }
    showMoney(roundInfo?: RoundInfo): [EnumBjlResult, number] {
        //return [this.recmV, this.currentMoney];
        if (roundInfo) {
            if (this.orecmV != EnumBjlResult.U && roundInfo.reverse) {
                this.recmV = this.orecmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;
            }
            else {
                this.recmV = this.orecmV;
            }
        }

        return [this.recmV, this.currentMoney];
    }
    resetRecm(): void {
        this.resetStrategy();
    }
    setBaseMoney(baseMoney: number) {
        // this.option.baseMoney = baseMoney;
        // this.option.startMoney = baseMoney;
        this.baseMoney = baseMoney;
        this.startMoney = baseMoney;
    }
    resetStrategy(): void {
        this.startIndex = 0;
        this.currentMoney = this.option.startMoney;
        this.prevMoney = 0;
        this.startMoney = this.option.startMoney;
        this.baseMoney = this.option.baseMoney;
        this.recmV = EnumBjlResult.U;
        this.gameStart = true;
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        if (!this.gameStart) return [EnumBjlResult.U, recmInfo.recmMoney];

        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            this.prevMoney = this.currentMoney;
            this.currentMoney += this.option.addStep;
        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            this.prevMoney = this.currentMoney;
            this.currentMoney += this.option.devideStep;
        }

        if (this.currentMoney < this.baseMoney) {
            this.prevMoney = this.baseMoney;
            this.currentMoney = this.startMoney;
        }
        this.orecmV = recmV;
        if (recmV == EnumBjlResult.U)
            return [recmV, recmInfo.recmMoney];
        else if (this.option.reverse || roundInfo.reverse)
            recmV = recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;

        this.recmV = recmV;
        return [recmV, this.currentMoney];
    }
    resetCurrentMoney() {
        this.currentMoney = this.startMoney;
    }
    stop() {
        this.gameStart = false;
    }
    restart() {
        this.gameStart = true;
    }
    isStart() {
        return this.gameStart;
    }
    canReset() {
        if (this.prevMoney >= this.option.resetLevel && this.currentMoney <= this.option.resetLevel) {
            return true;
        }
        return false;
    }
    strategyName: string;
    debugCompoenent: string = "";
    copyValue(valueObj: any): void {
        let obj = valueObj as NormalStepMoneyStrategy;
        if (obj) {
            //复制
            this.currentMoney = obj.currentMoney;
            this.gameStart = obj.gameStart;
            this.startIndex = obj.startIndex;
            this.prevMoney = obj.prevMoney;
            this.recmV = obj.recmV;
            this.orecmV = obj.orecmV;
        }
    }

}

export class MaxStepMoneyhStrategy extends NormalStepMoneyStrategy {
    protected _maxMoney: number = 0;
    public get maxMoney() {
        return this._maxMoney;
    }
    constructor(name: string, option?: INormalStepOption | null, start?: boolean) {
        super(name, option, start);
        this.resetStrategy();
    }
    resetStrategy(): void {
        super.resetStrategy();
        this._maxMoney = 0;
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        if (!this.gameStart) return [EnumBjlResult.U, recmInfo.recmMoney];

        this._maxMoney = recmInfo.roundSummaryInfo.winMoney - recmInfo.roundSummaryInfo.failMoney;
        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            this.prevMoney = this.currentMoney;
            this.currentMoney += this.option.addStep;
            // if (this.currentMoney > this._maxMoney && this._maxMoney > 0) {
            //     this.currentMoney = this.option.baseMoney;
            //     this._maxMoney = 0;
            // }
        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            // let maxM = (this.currentMoney + 10);
            // if(maxM > this._maxMoney){
            //     this._maxMoney = maxM;
            // }
            if (recmInfo.roundSummaryInfo.winMoney > recmInfo.roundSummaryInfo.failMoney) {
                recmInfo.roundSummaryInfo.resetSummaryInfo();
                this._maxMoney = 0;
                super.resetStrategy();
            }

            this.prevMoney = this.currentMoney;
            this.currentMoney += this.option.devideStep;

        }

        if (this.currentMoney < this.option.startMoney) {
            this.prevMoney = this.currentMoney;
            this.currentMoney = this.option.startMoney;
        }

        if (recmV == EnumBjlResult.U)
            return [recmV, recmInfo.recmMoney];
        else if (this.option.reverse)
            recmV = recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;

        return [recmV, this.currentMoney];
    }
    copyValue(valueObj: any): void {
        let obj = valueObj as MaxStepMoneyhStrategy;
        if (obj) {
            //复制
            super.copyValue(obj);
            this._maxMoney = obj._maxMoney;
        }
    }
}

export class MaxStepMoneyhStrategyV2 extends NormalStepMoneyStrategy {
    protected _maxMoney: number = 0;
    addStep: number = 0;
    devideStep: number = 0;
    public get maxMoney() {
        return this._maxMoney;
    }
    constructor(name: string, option?: INormalStepOption | null, start?: boolean) {
        super(name, option, start);
        this.resetStrategy();
    }
    resetStrategy(): void {
        super.resetStrategy();
        this._maxMoney = 0;
        this.addStep = this.option.addStep;
        this.devideStep = this.option.devideStep;
    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let recmV = roundInfo.userRecm;
        if (!this.gameStart) return [EnumBjlResult.U, recmInfo.recmMoney];

        this._maxMoney = recmInfo.roundSummaryInfo.winMoney - recmInfo.roundSummaryInfo.failMoney;
        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            this.prevMoney = this.currentMoney;
            this.currentMoney += this.addStep;
            // if (this.currentMoney > this._maxMoney && this._maxMoney > 0) {
            //     this.currentMoney = this.option.baseMoney;
            //     this._maxMoney = 0;
            // }
        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            this.prevMoney = this.currentMoney;
            this.currentMoney += this.devideStep;
        }

        if (this.currentMoney < this.option.startMoney) {
            this.prevMoney = this.currentMoney;
            this.currentMoney = this.option.startMoney;
        }

        if (recmV == EnumBjlResult.U)
            return [recmV, recmInfo.recmMoney];
        else if (this.option.reverse)
            recmV = recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;

        return [recmV, this.currentMoney];
    }
    copyValue(valueObj: any): void {
        let obj = valueObj as MaxStepMoneyhStrategyV2;
        if (obj) {
            //复制
            super.copyValue(obj);
            this._maxMoney = obj._maxMoney;
        }
    }
}
export interface IResetRecmStepOption {
    startMoney: number;
    addStep: number;
    devideStep: number;
    reverse: boolean; //true:赢了+100，输了-100
    resetLevel: number;
    baseMoney: number;
    betArray?: EnumBjlResult[];
}
export class ResetRecmStepMoneyStrategy {
    betArray: EnumBjlResult[] = [];
    option: INormalStepOption;
    prevMoney: number = 0;
    currentMoney: number = 0;
    startIndex: number = 0;
    baseMoney: number = 0;
    startMoney: number = 0;
    recmV: EnumBjlResult = EnumBjlResult.U;

    constructor(name: string, option?: IResetRecmStepOption | null) {
        this.strategyName = name;
        if (option) {
            this.option = option;
        }
        else {
            this.option = {
                baseMoney: 100,
                startMoney: 100,
                addStep: 100,
                devideStep: -100,
                reverse: false,
                resetLevel: 800,
            };
        }
        this.resetStrategy();
    }
    showMoney(): [EnumBjlResult, number] {
        return [this.recmV, this.currentMoney];
    }
    resetRecm(): void {
        this.resetStrategy();
    }
    resetStrategy(): void {
        this.startIndex = 0;
        this.currentMoney = this.option.startMoney;
        this.prevMoney = 0;
        this.startMoney = this.option.startMoney;
        this.baseMoney = this.option.baseMoney;
        this.recmV = EnumBjlResult.U;
        this.betArray = this.option.betArray ?? [];
    }
    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {

        if (recmInfo.summaryInfo.prevResult == EnumBetResult.Success) {
            this.prevMoney = this.currentMoney;
            this.currentMoney += this.option.addStep;
        }
        else if (recmInfo.summaryInfo.prevResult == EnumBetResult.Fail) {
            this.prevMoney = this.currentMoney;
            this.currentMoney += this.option.devideStep;
        }

        if (this.currentMoney < this.startMoney) {
            this.prevMoney = this.currentMoney;
            this.currentMoney = this.startMoney;
        }

        let length = recmInfo.roundSummaryInfo.zCount + recmInfo.roundSummaryInfo.xCount;
        let recmV = this.betArray[length % this.betArray.length];
        if (recmV == EnumBjlResult.U)
            return [recmV, recmInfo.recmMoney];
        else if (this.option.reverse)
            recmV = recmV == EnumBjlResult.Z ? EnumBjlResult.X : EnumBjlResult.Z;

        this.recmV = recmV;
        return [recmV, this.currentMoney];
    }
    strategyName: string;
    debugCompoenent: string = "";
    copyValue(valueObj: any): void {
        let obj = valueObj as ResetRecmStepMoneyStrategy;
        if (obj) {
            //复制
            this.currentMoney = obj.currentMoney;
            this.startIndex = obj.startIndex;
            this.prevMoney = obj.prevMoney;
            this.recmV = obj.recmV;
            this.betArray = obj.betArray;
            this.baseMoney = obj.baseMoney;
            this.startMoney = obj.startMoney;
        }
    }

}
